package scatter.order.rest.service.impl;

import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import scatter.common.rest.exception.BusinessDataNotFoundException;
import scatter.common.rest.exception.BusinessException;
import scatter.common.rest.validation.DictService;
import scatter.common.state.StateDependMultiple;
import scatter.order.pojo.constant.OrderConstants;
import scatter.order.pojo.param.UpdateOrderStatusParam;
import scatter.order.pojo.po.Order;
import scatter.order.pojo.po.OrderGoods;
import scatter.order.pojo.po.OrderRefund;
import scatter.order.pojo.po.OrderRefundGoods;
import scatter.order.rest.service.IOrderGoodsService;
import scatter.order.rest.service.IOrderRefundGoodsService;
import scatter.order.rest.service.IOrderRefundService;
import scatter.order.rest.service.IOrderService;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *
 * </p>
 *
 * @author yangwei
 * @since 2021-07-05 04:25
 */
@Slf4j
public class DefaultOrderStatusFrameworkServiceImpl extends AbstractOrderStatusFrameworkServiceImpl{

	@Autowired
	protected IOrderService iOrderService;
	@Autowired
	protected DictService dictService;
	@Autowired
	protected IOrderGoodsService iOrderGoodsService;

	@Autowired
	protected IOrderRefundService iOrderRefundService;

	@Autowired
	protected IOrderRefundGoodsService iOrderRefundGoodsService;


	/**
	 * 订单状态状态依赖机
	 */
	public static StateDependMultiple<String,String> orderStatusMachine = null;
	static {
		orderStatusMachine = new StateDependMultiple<>();
		orderStatusMachine.addDependItem(OrderConstants.OrderStatusItem.wait_pay.itemValue(), OrderConstants.OrderStatusItem.paid.itemValue());
		orderStatusMachine.addDependItem(OrderConstants.OrderStatusItem.wait_pay.itemValue(), OrderConstants.OrderStatusItem.closed.itemValue());
		orderStatusMachine.addDependItem(OrderConstants.OrderStatusItem.wait_pay.itemValue(), OrderConstants.OrderStatusItem.closed_expire.itemValue());

		orderStatusMachine.addDependItem(OrderConstants.OrderStatusItem.paid.itemValue(), OrderConstants.OrderStatusItem.refund.itemValue());
		orderStatusMachine.addDependItem(OrderConstants.OrderStatusItem.paid.itemValue(), OrderConstants.OrderStatusItem.refunding.itemValue());
		orderStatusMachine.addDependItem(OrderConstants.OrderStatusItem.paid.itemValue(), OrderConstants.OrderStatusItem.refund_part_goods.itemValue());
		orderStatusMachine.addDependItem(OrderConstants.OrderStatusItem.paid.itemValue(), OrderConstants.OrderStatusItem.refunding_part_goods.itemValue());

		orderStatusMachine.addDependItem(OrderConstants.OrderStatusItem.refunding.itemValue(), OrderConstants.OrderStatusItem.refund.itemValue());
		orderStatusMachine.addDependItem(OrderConstants.OrderStatusItem.refunding_part_goods.itemValue(), OrderConstants.OrderStatusItem.refund_part_goods.itemValue());


	}

	/**
	 * 订单状态，类似一个状态机，有一些状态有先后顺序，不能随便更新订单状态
	 * @param param
	 * @return
	 */
	@Override
	protected boolean preUpdate(UpdateOrderStatusParam param) {

		// 对订单状态进行校验
		Order byOrderNo = iOrderService.getByOrderNo(param.getOrderNo());
		String orderStatus = dictService.getValueById(byOrderNo.getStatusDictId());

		List<String> depend = orderStatusMachine.getDepend(orderStatus);
		if (isEmpty(depend)) {
			throw new BusinessException("订单状态流转错误，当前订单状态不可修改");
		}
		long count = depend.stream().filter(item -> isEqual(item, param.getStatus())).count();
		if(count == 0){
			throw new BusinessException(StrUtil.format("订单状态流转错误{},当前订单状态 {}，只能流转到 {}",param.getStatus(),orderStatus,depend.stream().collect(Collectors.joining(","))));
		}

		return super.preUpdate(param);
	}

	@Override
	public boolean doUpdateOrderStatus(UpdateOrderStatusParam param) {
		// 获取订单
		Order byOrderNo = iOrderService.getByOrderNo(param.getOrderNo());
		if (byOrderNo == null) {
			throw new BusinessDataNotFoundException("订单不存在 orderNo="+ param.getOrderNo());
		}
		// 要更新的状态
		OrderConstants.OrderStatusItem orderStatusItem = OrderConstants.OrderStatusItem.valueOf(param.getStatus());

		// 要更新的字典值状态id值
		String idByGroupCodeAndValue = dictService.getIdByGroupCodeAndValue(orderStatusItem.groupCode(), orderStatusItem.itemValue());
		// 退款只支持以下状态
		boolean equalRefund = isEqualAny(orderStatusItem.itemValue()
				, OrderConstants.OrderStatusItem.refunding.itemValue()
				, OrderConstants.OrderStatusItem.refund.itemValue()
				, OrderConstants.OrderStatusItem.refunding_part_goods.itemValue()
				, OrderConstants.OrderStatusItem.refund_part_goods.itemValue()
		);
		// 退款其它状态
		boolean equalAny = isEqualAny(orderStatusItem.itemValue()
				, OrderConstants.OrderStatusItem.paid.itemValue()
				, OrderConstants.OrderStatusItem.closed.itemValue()
				, OrderConstants.OrderStatusItem.closed_expire.itemValue()
				, OrderConstants.OrderStatusItem.wait_pay.itemValue()
		);
		// 退款支持
		if (equalRefund) {

			if (isStrEmpty(param.getOrderRefundNo())) {
				throw new BusinessException("退款退款单号不能为空");
			}
			OrderRefund orderRefund = iOrderRefundService.getByRefundNo(param.getOrderRefundNo());
			if (orderRefund != null) {
				log.info("存在退款单数据,更新退款单状态,orderRefundNo={},orderStatusItem={}",param.getOrderRefundNo(),orderStatusItem.itemValue());
				orderRefund.setStatusDictId(idByGroupCodeAndValue);
				boolean b = iOrderRefundService.updateById(orderRefund);
				if (!b) {
					throw new BusinessException("修改退款单表状态失败，因其返回false");
				}

				// 更新退款商品
				List<OrderRefundGoods> byOrderRefundId = iOrderRefundGoodsService.getByOrderRefundId(orderRefund.getId());
				if (!isEmpty(byOrderRefundId)) {

					List<String> goodsIds = byOrderRefundId.stream().map(OrderRefundGoods::getGoodsId).collect(Collectors.toList());

					// 退款支持的商品设置退款状态
					List<OrderGoods> orderGoodsList = iOrderGoodsService.getByGoodsIdsAndOrderId(goodsIds,byOrderNo.getId());
					orderGoodsList.stream().forEach(g -> g.setStatusDictId(idByGroupCodeAndValue));
					boolean b1 = iOrderGoodsService.updateBatchById(orderGoodsList);
					if (!b1) {
						throw new BusinessException("退款状态，更新订单商品状态失败");
					}
				}else {
					log.info("退款无商品数据,orderRefundNo={}",param.getOrderRefundNo());
				}
			}else {
				throw new BusinessException(StrUtil.format("退款单不存在,orderRefundNo={}",param.getOrderRefundNo()));
			}
		}else if(equalAny){
			log.info("更新订单下的全部商品状态");
			List<OrderGoods> byOrderId = iOrderGoodsService.getByOrderId(byOrderNo.getId());
			byOrderId.stream().forEach(g -> g.setStatusDictId(idByGroupCodeAndValue));
			iOrderGoodsService.updateBatchById(byOrderId);
		}else {
			throw new BusinessException(StrUtil.format("暂不支持的订单状态变更，status={}",orderStatusItem.itemValue()));
		}

		String orderStatusDictId = iOrderService.computeOrderStatusByGoodsStatus(byOrderNo.getId());

		if (isStrEmpty(orderStatusDictId)) {
			log.info("根据商品计算订单状态字典id为空");
			orderStatusDictId = idByGroupCodeAndValue;
		}
		byOrderNo.setStatusDictId(orderStatusDictId);

		boolean orderResult = iOrderService.updateById(byOrderNo);
		if (!orderResult) {
			throw new BusinessException("修改订单表状态失败，因其返回false");
		}

		return true;
	}
}
